
https://labuladong.online/algo/data-structure-basic/linkedlist-basic/
今天是學習的第 18 天,主要學習了用陣列加強哈希表(ArrayHashMap):
randomKey() API如果我們想在基於哈希表的 API 之上,新增一個 randomKey() API,可以在 O(1) 的時間複雜度內返回一個隨機的鍵,這件事並沒有那麼地容易。
使用額外的陣列來儲存所有鍵,結合哈希表建立雙向映射:
arr:按順序儲存所有鍵值對 key-value 節點map:建立 key -> 陣列索引 的映射關係O(1) 刪除陣列元素
普通陣列刪除中間元素需要移動資料,時間複雜度是 O(n),解決方案:
class MyArrayHashMap {
    constructor() {
        this.map = new Map();  // key -> 陣列索引
        this.arr = [];         // 儲存所有 key-value 節點
    }
    
    put(key, val) {
        if (this.containsKey(key)) {
            // 修改現有值
            let i = this.map.get(key);
            this.arr[i].val = val;
        } else {
            // 新增:加到陣列尾部,建立映射
            this.arr.push(new Node(key, val));
            this.map.set(key, this.arr.length - 1);
        }
    }
    
    remove(key) {
        // 交換到尾部 -> 刪除尾部 -> 更新映射
        let index = this.map.get(key);
        let lastElement = this.arr[this.arr.length - 1];
        
        this.arr[index] = lastElement;
        this.map.set(lastElement.key, index);
        
        this.arr.pop();
        this.map.delete(key);
    }
    
    randomKey() {
        let randomIndex = Math.floor(Math.random() * this.arr.length);
        return this.arr[randomIndex].key;
    }
}